package com.hyx.api.service.impl.pc_admin;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hyx.api.domain.CustomerWithdraw;
import com.hyx.api.domain.RecycleOrder;
import com.hyx.api.domain.User;
import com.hyx.api.domain.vo.KeyValueVo;
import com.hyx.api.domain.vo.PcIndexStatisticsVo;
import com.hyx.api.domain.vo.PcOfferPerVo;
import com.hyx.api.domain.vo.PcOperatorPerVo;
import com.hyx.api.enums.RecycleOrderStatusEnum;
import com.hyx.api.enums.UserTypeEnum;
import com.hyx.api.enums.WithdrawStatusEnum;
import com.hyx.api.mapper.*;
import com.hyx.api.service.pc_admin.IStatisticsService;
import com.ruoyi.common.core.domain.AjaxResult;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class IStatisticsServiceImpl implements IStatisticsService {

    private final RecycleOrderMapper recycleOrderMapper;
    private final CustomerWithdrawMapper withdrawMapper;
    private final InquiryOrderMapper inquiryOrderMapper;
    private final OfferOrderMapper offerOrderMapper;
    private final RefundOrderMapper refundOrderMapper;
    private final SpreadOrderMapper spreadOrderMapper;
    private final WalletChangeInfoMapper walletChangeInfoMapper;
    private final UserMapper userMapper;

    @Override
    public AjaxResult queryIndexStatistics() {
        PcIndexStatisticsVo resDO = new PcIndexStatisticsVo();
        LambdaQueryWrapper<RecycleOrder> recycleWrapper = Wrappers.lambdaQuery();
        recycleWrapper.eq(RecycleOrder::getStatus, RecycleOrderStatusEnum.NO_PAY.code());
        resDO.setWaitPayCount(recycleOrderMapper.selectCount(recycleWrapper));
        recycleWrapper.clear();
        recycleWrapper.eq(RecycleOrder::getStatus, RecycleOrderStatusEnum.NO_SEND.code());
        resDO.setWaitShipmentsCount(recycleOrderMapper.selectCount(recycleWrapper));
        recycleWrapper.clear();
        recycleWrapper.eq(RecycleOrder::getStatus, RecycleOrderStatusEnum.NO_RECEIVING.code());
        resDO.setWaitReceivingCount(recycleOrderMapper.selectCount(recycleWrapper));
        LambdaQueryWrapper<CustomerWithdraw> withdrawWrapper = Wrappers.lambdaQuery();
        withdrawWrapper.eq(CustomerWithdraw::getStatus, WithdrawStatusEnum.WAIT_WITHDRAW.code());
        resDO.setWaitWithdrawCount(withdrawMapper.selectCount(withdrawWrapper));
        recycleWrapper.clear();
        recycleWrapper.eq(RecycleOrder::getStatus, RecycleOrderStatusEnum.FINISH.code());
        resDO.setAlreadyDoneCount(recycleOrderMapper.selectCount(recycleWrapper));
        resDO.setInquiryCount(inquiryOrderMapper.selectCount(new LambdaQueryWrapper<>()));
        resDO.setOfferCount(offerOrderMapper.selectCount(new LambdaQueryWrapper<>()));
        resDO.setRecycleCount(recycleOrderMapper.selectCount(new LambdaQueryWrapper<>()));
        resDO.setRefundCount(refundOrderMapper.selectCount(new LambdaQueryWrapper<>()));
        resDO.setSpreadCount(spreadOrderMapper.selectCount(new LambdaQueryWrapper<>()));
        //收支记录列表-最近7天
        List<KeyValueVo> budgetList = new ArrayList<>();
        DateTime startTime = DateUtil.offsetDay(new Date(), -6);
        long diffDay = DateUtil.between(startTime, new Date(), DateUnit.DAY, true);
        for (int i = 0; i < diffDay; i++) {
            KeyValueVo baseKV = new KeyValueVo();
            DateTime queTime = DateUtil.offsetDay(startTime, i);
            baseKV.setKey(DateUtil.formatDate(queTime).split("-")[2] + "日");
            JSONObject jo = new JSONObject();
            BigDecimal income = walletChangeInfoMapper.incomeForDate(queTime);
            jo.put("income", income == null ? BigDecimal.ZERO : income);
            BigDecimal expend = walletChangeInfoMapper.expendForDate(queTime);
            jo.put("expend", expend == null ? BigDecimal.ZERO : expend);
            baseKV.setValue(jo);
            budgetList.add(baseKV);
        }
        resDO.setBudgetList(budgetList);
        //店员业绩
        List<PcOperatorPerVo> pcOperatorPerVos = inquiryOrderMapper.queryPcOperatorPerList();
        Set<Long> operatorIds = pcOperatorPerVos.stream().map(PcOperatorPerVo::getOperatorId).collect(Collectors.toSet());
        resDO.setOperatorPerformance(pcOperatorPerVos);
        List<PcOfferPerVo> pcOfferPerVos = offerOrderMapper.queryPcOfferPerList();
        Set<Long> offerIds = pcOfferPerVos.stream().map(PcOfferPerVo::getOperatorId).collect(Collectors.toSet());
        operatorIds.addAll(offerIds);
        resDO.setRecycleOperatorPerformance(pcOfferPerVos);
        if (!operatorIds.isEmpty()) {
            List<User> users = userMapper.selectBatchIds(operatorIds);
            Map<Long, String> operatorMap = users.stream().collect(Collectors.toMap(User::getId, User::getNickName));
            for (PcOperatorPerVo operatorPerVo : pcOperatorPerVos) {
                operatorPerVo.setOperatorName(operatorMap.get(operatorPerVo.getOperatorId()));
            }
            for (PcOfferPerVo pcOfferPerVo : pcOfferPerVos) {
                pcOfferPerVo.setOperatorName(operatorMap.get(pcOfferPerVo.getOperatorId()));
            }
        } else {
            //默认添加6个店员
            LambdaQueryWrapper<User> userWrapper = Wrappers.lambdaQuery();
            userWrapper.eq(User::getType, UserTypeEnum.SHOP_OPERATOR.code());
            userWrapper.orderByAsc(User::getId);
            userWrapper.last("limit 6");
            List<User> operators = userMapper.selectList(userWrapper);
            for (User operator : operators) {
                PcOperatorPerVo operatorPerVo = new PcOperatorPerVo();
                operatorPerVo.setOperatorId(operator.getId());
                operatorPerVo.setOperatorName(operator.getNickName());
                pcOperatorPerVos.add(operatorPerVo);
            }
            //默认添加6个报价师
            userWrapper.clear();
            userWrapper.eq(User::getType, UserTypeEnum.OFFER_OPERATOR.code());
            userWrapper.orderByAsc(User::getId);
            userWrapper.last("limit 6");
            List<User> offers = userMapper.selectList(userWrapper);
            for (User offer : offers) {
                PcOfferPerVo offerPerVo = new PcOfferPerVo();
                offerPerVo.setOperatorId(offer.getId());
                offerPerVo.setOperatorName(offer.getNickName());
                pcOfferPerVos.add(offerPerVo);
            }
        }
        return AjaxResult.success(resDO);
    }
}
